﻿#include<iostream>
//面向对象的三大特征：封装 继承 多态

//this指针

//类的6个默认成员函数：
// 
//构造函数：
//虽然名称是构造，但是构造函数的主要任务并不是开空间，创造函数，而是类似init的初始化对象
//
// 特点：
// 函数名与类名相同（init就不用再写了）
// 无返回值
// 对象实例化时编译器自动调用
// 构造函数可以重载
// !函数重载：可以写多个构造函数，多种初始化方式（参数的变化）
// date d2(a,b,c);
// date d1;
// 
// //全缺省，和无参构成重载但是无参调用时会产生歧义
// Date(int a=1,int b=1,int c=3);
// Date()
// {
//   a=9；
//   ...
// }
// 
// //！！！一般情况：建议每个类都可以写一个全缺省的构造函数（好用：可以传参也可以不传参，传参不能跳着传，必须连续）
// 
// //C
// ST st;
// STInit(&st);
// //C++
// Stack st;
//

//默认构造函数：无参构造函数/全缺省构造函数/编译器自动生成的构造函数（不传参数就可以调用的函数就是默认构造函数）
//且这三种只能存在一个
// 
// 
// 如果传了参数，就不是默认构造
//
// 一般情况构造函数都需要显示地明确的实现
// 只有少数的情况下可以让编译器自己生成 
//
// 实践总结：
// 如果没有管理资源，一般情况下不需要写拷贝构造，默认生成的拷贝构造就够用：Date
// 如果是自定义类型的成员，内置类型没有指向资源，也类似默认生成的拷贝构造既可以：MYqueue
// 一般情况，不需要显示的写析构函数，就不需要写拷贝构造
// 如果内部有指针或者一些指向资源，需要显示析构函数，通常就需要显示写构造：完成深拷贝Stack Queue list
//
//



//析构函数
// 对象在销毁的时候会自动调用析构函数，完成对象中的资源清理工作（类似destroy）
//   没有开辟新的空间的对象不需要析构函数对其销毁
// 特点：
// 析构函数名，是在类名面前加上字符~
// 无参数无返回值（不能写）、一个类一个析构函数，无参数不重载
// 析构函数不能重载
//对象生命周期结束，C++自动生成调用
//Stack::~Stack()
//{
//  free(_a);
//  _a=nullptr;
// 。。。
//}
// //C
// bool ret=STEmpty(&st);
// STDestroy(&st);
// 
// return ret;
// //C++
// return st.Empty();

//默认生成的析构函数：对内置类型不做处理（指针也不置空释放（内存泄漏）），对自定义类型去调用它的析构

//拷贝构造函数（特殊的成员函数）
// 拷贝构造函数是构造函数的一个重载形式
// 拷贝函数的参数只有一个而且必须是类类型对象的引用，使用值传递的方式编译器直接报错，因为会引发无穷递归调用
// Date d3(d2);
// 语法逻辑上，传值传参会调用拷贝构造，拷贝构造也要传参，就会造成无穷递归，
// 所以拷贝构造的参数必须是引用
// 
//运算符重载
//为了增加代码的可读性引入了运算符重载，运算符重载是具有特殊函数名的函数，也具有其返回值类型，函数名以及参数列表，其返回类型与参数列表与普通的函数类似
// 函数名字为，关键字operator后面接需要重载的运算符符号
// 函数原型：返回值类型operator操作符（参数列表）
// bool operator<(const Date& d1,const Date& d2)
// Date  operator++(Date& d)
//!!!重载操作必须至少有一个类类型的参数
//! int operator-(int1,intr);
//注意：（这几个运算符是不能重载的）  .*（点心：调用成员函数的指针） ::（域作用限定符） sizeof  ?:(三目选择)  .（对象点）
//两个都是内置类型❌
//
// 赋值重载
// //复制拷贝/赋值重载
//一个已经存在的对象，拷贝赋值给另一个（不存在构造，也就不叫拷贝构造）
////！！！
// //如果不显示写赋值重载/编译器会默认生成:和拷贝构造的作用类似：内置类型直接赋值，自定义类型成员变量需要调用对应的赋值运算符重载完成赋值
//

//引用返回：
//如果返回对象是一个临时对象或者局部对象，出了当前函数的作用域，就销毁了，不能用引用返回：因为引用的对象在函数的栈帧中已经销毁了
//野指针/野指针
//虽然引用返回可以减少赋值拷贝/但是出了函数作用域返回对象还在，才能用引用返回
//
// 引用返回的正确使用场景：
// 静态变量：static（出作用域对象仍然在）
// 对象还没有析构/那就可以使用引用返回，减少拷贝
//
// 返回对象函数内析构/传值返回（无法使用地址）（有赋值拷贝）（不出现野指针）；
// 返回对象函数内不销毁/引用返回（本质是地址）（减少拷贝）（可能出现野指针）
//

//取地址运算符的重载






























